#!/usr/bin/python

#-------------------------------------------------------------------------------
# Name:        backup
# Purpose:     To backup and manage storage of servers.
#
# Author:      Donald L Talbert , www.bwhgaming.com
#
# Created:     20/09/2012
# Copyright:   (c) Donald L Talbert 2012
# Licence:     MIT
#-------------------------------------------------------------------------------

import shutil
import os
import logging
import ConfigParser
import datetime
import threading
import time

import loadconfig


class Backup(object):
    """
    This handles backing up the server according to the configuration file.
    """
    def __init__(self):
        """
        Sets class varables.
        """

		# Load varables from configuration...
        lc = loadconfig.LoadConfig()
        self.backupDir = lc.backupDirectory
        self.serverDir = lc.serverDirectory
        self.command = lc.command
        self.gameName = lc.GameName
        self.numAllowedBackups = lc.maxBackups
        self.compressionType = lc.compressionType
        self.timeBetweenBackups = int(lc.timeBetweenBackups)

        # Load varables from class functions
        self.numExistingBackups = self.NumExistingBackups()
        self.time = self.GetTime() # Gets current time
        self.oldBackup = self.OldestBackup() # Gets the oldest backup.
        self.backupName = self.gameName + '-' + self.time # Sets the backup name.
        self.archiveName = os.path.join(self.backupDir, self.backupName) # sets the backup path + name


    def GetTime(self):
        """
        Returns the current time formatted in a human friendly way as a
        string to insert to the filename of a backup.

        """
        now = datetime.datetime.now()
        time = str(now.date()) + "_" + str(now.hour) + "h-" + str(now.minute) + 'm'
        return time


    def NumExistingBackups(self):
        """
        returns the number of existing backups.

        """
        numBackups = len(os.listdir(self.backupDir))
        return numBackups


    def OldestBackup(self):
        """
        Returns the oldest backup file.

        """
        backupsList = os.listdir(self.backupDir)
        temp = []
        for backupFile in backupsList:
            archiveName = os.path.join(self.backupDir, backupFile)
            temp.append([os.stat(archiveName).st_ctime, backupFile])

        temp2 = sorted(temp, reverse = False, key=lambda test: test[0]) #Reverse was True

        try:
            strOldestBackup = os.path.join(self.backupDir, temp2[0][1])
        except IndexError: # an Index error means there is no backups in the directory.
            return 0
        print strOldestBackup
        return strOldestBackup

    def CheckIfBackupDirExist(self):
        """
        Returns the oldest backup file.

        """
        if os.path.exists(self.backupDir) == False: # Checks if the directory to backup the files exists. If not creates one.
            logging.info("Directory does not exist. Creating: " + self.backupDir)
            os.mkdir(self.backupDir)
            logging.info("Directory created.")
            return False
        else:
            return True

    def CheckIfServerDirExist(self):
        """
        Checks if the server directory exists.

        """
        if os.path.exists(self.serverDir) == False: # Checks if the server directory exists before backing up. If not debugs and returns.
            logging.warning("Directory " + self.serverDir + " does not exist. Please check your config. Aborting backup.")
            return False
        else:
            return True

    def CheckIfBackupsFull(self):
        """
        Checks if backup directory is fulland returns a bool. If its full it
        deletes the backup. Returns True if full and returns False if not full.
        """
        if int(self.numAllowedBackups) <= int(self.numExistingBackups): # If full return True.
            logging.info("Max allowed backups reached.")
            logging.info("Removing oldest backup, " + self.oldBackup)
            os.remove(self.oldBackup)
            logging.info("Backup Removed.")
            return True


    def Backup(self, timed=True):
        """
        Backups the directory

        """
        self.CheckIfBackupDirExist() # Makes sure the backup directory exists or creates it

        if self.CheckIfServerDirExist(): # Checks if the directory we are even backing up exists.
            pass
        else:
            return None

        self.CheckIfBackupsFull() # Makes sure there is room in the backup directory

        # Creates a backup
        logging.info("Creating " + self.compressionType + " backup of " + str(self.serverDir) + " at " + str(self.archiveName) + " Using " + self.compressionType)
        shutil.make_archive(self.archiveName, self.compressionType, self.serverDir) # Takes the archive path, compression type, and serverDir to backup.
        logging.info("Backup completed")
        return None


if __name__ == '__main__':
	pass
